package com.origin.src.datasource.sharding;

import org.apache.shardingsphere.encrypt.config.EncryptRuleConfiguration;
import org.apache.shardingsphere.encrypt.config.rule.EncryptColumnItemRuleConfiguration;
import org.apache.shardingsphere.encrypt.config.rule.EncryptColumnRuleConfiguration;
import org.apache.shardingsphere.encrypt.config.rule.EncryptTableRuleConfiguration;
import org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
import org.apache.shardingsphere.sharding.api.config.rule.ShardingTableReferenceRuleConfiguration;
import org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;
import org.apache.shardingsphere.sharding.api.config.strategy.keygen.KeyGenerateStrategyConfiguration;
import org.apache.shardingsphere.sharding.api.config.strategy.sharding.ShardingStrategyConfiguration;
import org.apache.shardingsphere.sharding.api.config.strategy.sharding.StandardShardingStrategyConfiguration;

import java.util.*;

public class ShardingConfigTool {

    public static ShardingRuleConfiguration getRuleConfig(ShardingConfig shardingConfig) {
        ShardingRuleConfiguration config = new ShardingRuleConfiguration();

        config.getShardingAlgorithms().put(
                shardingConfig.getDbShardingAlgorithmName(), new AlgorithmConfiguration(shardingConfig.getDbShardingAlgorithmName(), new Properties()));

        config.getShardingAlgorithms().put(
                shardingConfig.getTbShardingAlgorithmName(), new AlgorithmConfiguration(shardingConfig.getTbShardingAlgorithmName(), new Properties()));

        config.getKeyGenerators().put(
                shardingConfig.getKeyGeneratorName(), new AlgorithmConfiguration(shardingConfig.getKeyGeneratorName(), new Properties()));

        config.getAuditors().put(
                shardingConfig.getAuditStrategy(), new AlgorithmConfiguration(shardingConfig.getAuditStrategy(), new Properties()));


        config.getTables().add(getTableRuleConfig(shardingConfig));
        config.getBindingTableGroups().add(new ShardingTableReferenceRuleConfiguration("app", "t_user"));
        return config;
    }


    public static ShardingTableRuleConfiguration getTableRuleConfig(ShardingConfig conf) {

        ShardingTableRuleConfiguration result = new ShardingTableRuleConfiguration(
                conf.getLogicTable(),
                conf.getDbNamePrefix() +
                        "${0.." + conf.getDbMax() + "}." +
                        conf.getLogicTable() + "_${0.." + conf.getTbMax() + "}");

        //指定主键id生成方式，snowflake=雪花算法 org.apache.shardingsphere.infra.algorithm.keygen.snowflake.SnowflakeKeyGenerateAlgorithm
        result.setKeyGenerateStrategy(new KeyGenerateStrategyConfiguration(conf.getPrimaryKeyColumn(), conf.getKeyGeneratorName()));

        //禁用分片审计策略，不影响历史逻辑的情况下应该开启强制分片键存在的策略
//        result.setAuditStrategy(new ShardingAuditStrategyConfiguration(Collections.singleton("sharding_key_required_auditor"), true));

        //数据库分片策略
        ShardingStrategyConfiguration dbSharding
                = new StandardShardingStrategyConfiguration(
                conf.getDbShardColumn(), conf.getDbShardingAlgorithmName());

        result.setDatabaseShardingStrategy(dbSharding);

        ShardingStrategyConfiguration tableSharding
                = new StandardShardingStrategyConfiguration(
                conf.getTbShardColumn(), conf.getTbShardingAlgorithmName());

        result.setTableShardingStrategy(tableSharding);


        return result;
    }


    public static EncryptRuleConfiguration getEncryptRuleConfiguration()  {
        Properties props = new Properties();
        props.setProperty("aes-key-value", "123456");
        props.setProperty("digest-algorithm-name", "SHA-1");
//        EncryptColumnRuleConfiguration columnConfigAes = new EncryptColumnRuleConfiguration("username", new EncryptColumnItemRuleConfiguration("username", "name_encryptor"));
        EncryptColumnRuleConfiguration loginPwdConf = new EncryptColumnRuleConfiguration("login_password", new EncryptColumnItemRuleConfiguration("login_pwd", "aes_encryptor"));

//        loginPwdConf.setAssistedQuery(new EncryptColumnItemRuleConfiguration("assisted_query_pwd", "pwd_encryptor"));
//        loginPwdConf.setLikeQuery(new EncryptColumnItemRuleConfiguration("like_pwd", "like_encryptor"));

        EncryptTableRuleConfiguration encryptTableRuleConfig = new EncryptTableRuleConfiguration("t_user", List.of(loginPwdConf));
        Map<String, AlgorithmConfiguration> encryptAlgorithmConfigs = new HashMap<>();
        encryptAlgorithmConfigs.put("aes_encryptor", new AlgorithmConfiguration("AES", props));
//        encryptAlgorithmConfigs.put("pwd_encryptor", new AlgorithmConfiguration("assistedTest", props));
//        encryptAlgorithmConfigs.put("like_encryptor", new AlgorithmConfiguration("CHAR_DIGEST_LIKE", new Properties()));
        return new EncryptRuleConfiguration(Collections.singleton(encryptTableRuleConfig), encryptAlgorithmConfigs);
    }


}
